﻿using ApiConceptsFramework.Concepts.Properties;
using ApiConceptsFramework.Contract;
using FluentAssertions;
using NUnit.Framework;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace test.ApiConceptsFramework.Concepts.Properties
{
	[TestFixture]
	public class NumberOfOverloadsTests
	{
// ReSharper disable UnusedMember.Local
		class TestClass
		{
			public TestClass(bool p1) { }
			public TestClass(string p1) { }
			public TestClass(int p1) { }
			
			public void Method1(bool p1) { }
			public void Method1(string p1) { }
			public void Method1(bool p1, string p2) { }
			public void Method1(string p1, bool p2) { }
			public void Method1(string p1, string p2) { }
			public void Method1(string p1, string p2, string p3) { }
		}
// ReSharper restore UnusedMember.Local

		[Test]
		public void Complexity_equals_number_of_overloads_above_member()
		{
			//Arrange
			var measurableProperty = new NumberOfOverloads();
			var method = typeof(TestClass).GetMethod("Method1", new[] { typeof(string), typeof(bool) });
			
			//Act
			var target = new MeasurableTarget {Type = typeof (TestClass), Member = method};
			var result = measurableProperty.CalculateComplexity(target, IDE.VisualStudioOrSimilar);

			//Assert
			result.Should().Be(NumberOfOverloads.NumberOfOverloadsToComplexityFactor*3, "because there are 3 overloads above method Method1(string,bool)");
			Console.WriteLine("Complexity of Method1(bool p1, string p2) = " + result);
		}

		[Test]
		public void Complexity_is_0_for_first_overload()
		{
			//Arrange
			var measurableProperty = new NumberOfOverloads();
			var method = typeof(TestClass).GetMethod("Method1", new[] { typeof(bool) });

			//Act
			var target = new MeasurableTarget { Type = typeof(TestClass), Member = method };
			var result = measurableProperty.CalculateComplexity(target, IDE.VisualStudioOrSimilar);

			//Assert
			result.Should().Be(0);
			Console.WriteLine("Complexity of Method1(bool p1) = " + result);
		}

		[Test]
		public void Allows_calculation_for_constructors()
		{
			//Arrange
			var measurableProperty = new NumberOfOverloads();
			var method = typeof(TestClass).GetConstructor(new[] { typeof(string) });

			//Act
			var target = new MeasurableTarget { Type = typeof(TestClass), Member = method };
			var result = measurableProperty.CalculateComplexity(target, IDE.VisualStudioOrSimilar);

			//Assert
			result.Should().Be(NumberOfOverloads.NumberOfOverloadsToComplexityFactor*2, "because TestClass(string) is the third ctor overload");
			Console.WriteLine("Complexity of ctor(string p1) = " + result);
		}

		[Test]
		public void No_suggestions_are_made()
		{
			//Arrange
			var measurableProperty = new NumberOfOverloads();
			var method = typeof(TestClass).GetMember("Method1").First();

			//Act
			var target = new MeasurableTarget { Type = typeof(TestClass), Member = method };
			var result = measurableProperty.GetSuggestions(target, IDE.VisualStudioOrSimilar);

			//Assert
			result.Should().BeEmpty();
		}
	}
}
